﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YiYiTong.Rocket.Helper;
using YiYiTong.Rocket.Model;

namespace YiYiTong.Rocket.Business
{
    /// <summary>
    /// api接口验证
    /// </summary>
    public class OAuthBiz
    {
        #region 单例模式
        private OAuthBiz()
        {
        }

        private static OAuthBiz _instance;
        private static readonly object _syncObject = new object();

        public static OAuthBiz Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_syncObject)
                    {
                        if (_instance == null)
                        {
                            _instance = new OAuthBiz();
                        }
                    }
                }
                return _instance;
            }
        }
        #endregion 单例模式

        /// <summary>
        /// 检查token是否有效
        /// </summary>
        /// <param name="service"></param>
        /// <param name="token"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public bool CheckToken(string service, string token, out long userId)
        {
            bool checkRet = true; userId = 0;
            //检查接口是否需要验证token
            string strNoOAuthApi = ConfigHelper.AppSetting<string>("noOAuthApi");
            if (!string.IsNullOrEmpty(strNoOAuthApi))
            {
                string[] noOAuthApi = Utils.GetStrings(strNoOAuthApi, ",");
                if (noOAuthApi.Contains<string>(service.ToLower()))
                {
                    //无需验证token,直接返回
                    return checkRet;
                }
            }

            //下面开始验证token
            if (string.IsNullOrEmpty(token))
                checkRet = false;
            else
            {
                //redis缓存获取用户信息
                UserTokenModel user = GetUserInfo(token);
                if (user == null)
                {
                    //token不存在，移除该Key
                    checkRet = false; RedisService.Remove(token);
                }
                else if (user.ExpiredTime < DateTime.Now)
                {
                    //token已过期，移除该Key
                    checkRet = false; RedisService.Remove(token);
                }
                else
                    userId = user.UserId;
            }
            return checkRet;
        }

        #region token

        /// <summary>
        /// 根据token获取存储用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public UserTokenModel GetUserInfo(string token)
        {
            return RedisService.Get<UserTokenModel>(token);
        }

        /// <summary>
        /// 创建Token
        /// </summary>
        /// <param name="walletInfo"></param>
        /// <returns></returns>
        public string CreateToken(UserTokenModel userInfo)
        {
            string token = "";
            string data = JsonHelper.Serialize(userInfo);
            token = GetTokenKey(userInfo) + Utils.Md5Encrypt(data + ".rocket", Encoding.UTF8);
            return token;
        }

        /// <summary>
        /// 保存token并存储用户信息到缓存中
        /// </summary>
        /// <param name="walletInfo"></param>
        /// <returns></returns>
        public bool SetUserInfo(UserTokenModel userInfo)
        {
            string token = userInfo.Token;
            DateTime expiredTime = userInfo.ExpiredTime;
            if (string.IsNullOrEmpty(token))
                return false;
            TimeSpan exp = expiredTime - DateTime.Now;
            return RedisService.Set(token, userInfo, exp);
        }

        /// <summary>
        /// 移除所有Token
        /// </summary>
        /// <returns></returns>
        public bool RemoveToken(UserTokenModel userInfo)
        {
            string token = GetTokenKey(userInfo);
            List<String> keys = RedisService.SearchKeys(token + "*");
            if (keys.Count != 0)
            {
                RedisService.RemoveAll(keys);
            }
            return true;
        }

        /// <summary>
        /// 将该用户的登录状态全清理掉
        /// </summary>
        /// <param name="walletId"></param>
        /// <returns></returns>
        public bool RemoveToken(long userId, string machineCode = "")
        {
            string key = "token." + userId + "." + "*";
            if (!string.IsNullOrWhiteSpace(machineCode))
                key = "token." + userId + "." + machineCode + ".";
            List<String> keys = RedisService.SearchKeys(key);

            if (keys.Count != 0)
            {
                RedisService.RemoveAll(keys);
            }
            return true;
        }

        public string GetTokenKey(UserTokenModel userInfo)
        {
            return "token." + userInfo.UserId + "." + userInfo.MachineCode + ".";
        }

        #endregion token

        /// <summary>
        /// 检查无需data参数api接口
        /// </summary>
        /// <returns></returns>
        public bool CheckNoArgumentApi(string service)
        {
            string strNoArgumentApi = ConfigHelper.AppSetting<string>("noArgumentApi").ToLower();
            if (string.IsNullOrEmpty(strNoArgumentApi))
                return false;
            string[] noArgumentApi = Utils.GetStrings(strNoArgumentApi, ",");
            if (noArgumentApi.Contains<string>(service.ToLower()))
                return true;
            else
                return false;
        }

        /// <summary>
        /// 检查无需Sign参数api接口
        /// </summary>
        /// <returns></returns>
        public bool CheckNoSignApi(string service)
        {
            string apis = ConfigHelper.AppSetting<string>("noSignApi").ToLower();
            if (string.IsNullOrEmpty(apis))
                return false;
            string[] noArgumentApi = Utils.GetStrings(apis, ",");
            if (noArgumentApi.Contains<string>(service.ToLower()))
                return true;
            else
                return false;
        }
    }
}
